﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Net;
using System.Threading;
using System.IO;
using DSkin.Forms;
using SC;

namespace ClientProject
{
    public partial class FrmClient : Skin_VS_Dark
    {
        public FrmClient()
        {
            InitializeComponent();
        }

        private SocketClient socketClient;

        Dictionary<string, DS.Controls.DSFolderListItem> taskItemDic = new Dictionary<string, DS.Controls.DSFolderListItem>();

        //public List<string> taskList = new List<string>(); //当前任务列表
        public List<Common.TaskItemData> taskList2 = new List<Common.TaskItemData>(); //当前任务列表


        bool bContinue;
        /// <summary>
        /// 连接
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_Connect_Click(object sender, EventArgs e)
        {
            int port;
            Int32.TryParse(this.txt_Port.Text, out port);
            socketClient.ConnectServer(this.txt_IP.Text, port);
        }

        private void FrmClient_Load(object sender, EventArgs e)
        {
            Control.CheckForIllegalCrossThreadCalls = false;
            SC.BroadCastReceive clientBroadCast = new SC.BroadCastReceive();
            clientBroadCast.Start();

            clientBroadCast.getServiceIP += GetServiceIP;
            socketClient = new SocketClient();
            socketClient.recvEvent += Recv;
            socketClient.clientConnect += ClientConnect;

            System.Threading.Thread calcThread = new Thread(new ParameterizedThreadStart(Calculate));
            calcThread.IsBackground = true;
            calcThread.Start(taskList2);
            bContinue = true;

            //开机启动
            Microsoft.Win32.RegistryKey ms_run = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run", true);
            if (ms_run.GetValue(Application.ProductName)!=null && !ms_run.GetValue(Application.ProductName).ToString().Equals(Application.ExecutablePath.ToString()))
            {
                ms_run.SetValue(Application.ProductName, Application.ExecutablePath.ToString());
            }
            //this.WindowState = FormWindowState.Minimized;
            dSkinContextMenuStrip1.Renderer = new DS.Controls.DSMenuRender.MenuRender();

            this.BeginInvoke(new ThreadStart(delayHide));
        }
        /// <summary>
        /// 启动时隐藏窗口
        /// </summary>
        public void delayHide()
        {
            this.Hide();
        }

        /// <summary>
        /// 显示窗口
        /// </summary>
        private void RestoreWin()
        {
            //this.ShowInTaskbar = true;
            this.Visible = true;
            //this.WindowState = FormWindowState.Normal;
            this.Activate();
            this.BringToFront();
        }

        /// <summary>
        /// 从广播获取服务器IP后连接
        /// </summary>
        /// <param name="ip"></param>
        private void GetServiceIP(Common.ServerProfile serverProfile)
        {
            socketClient.ConnectServer(serverProfile.serverIp, serverProfile.serverPort);
        }

        /// <summary>
        /// 客户端连接成功 反馈已分配任务给服务端
        /// </summary>
        private void ClientConnect()
        {
            socketClient.Send(SC.MessageType.ClientConnect, taskList2);
            Common.Log.Info("发送当前任务列表给服务器");
        }

        /// <summary>
        /// 客户端接收消息处理
        /// </summary>
        /// <param name="socketSend"></param>
        /// <param name="messageType"></param>
        /// <param name="objBuf"></param> 
        public void Recv(Socket socketSend, SC.MessageType messageType, byte[] objBuf)
        {
            Console.WriteLine(messageType.ToString());
            Common.Log.Info("接收消息类型"+messageType.ToString());
            switch (messageType)
            {
                case SC.MessageType.RenderTask:
                    {
                        lock (taskList2)
                        {
                            taskList2.AddRange(MessagePack.DeserializeObject<List<Common.TaskItemData>>(objBuf));
                            for (int i = 0; i < taskList2.Count; i++)
                            {
                                Common.TaskItemData itemData = taskList2[i];
                                
                                if (!taskItemDic.ContainsKey(itemData.md5key))
                                {
                                    itemData.machineName = System.Environment.MachineName;
                                    socketClient.Send(SC.MessageType.RecvTaskSucceed, itemData);
                                    AddTaskItem(itemData);
                                }
                            }
                        }
                    }
                    break;

                case SC.MessageType.Pause:
                    bContinue = false;
                    break;
                case SC.MessageType.Continue:
                    bContinue = true;
                    break;

                case SC.MessageType.Delete:
                    Common.TaskItemData taskItemData = MessagePack.DeserializeObject<Common.TaskItemData>(objBuf);
                    Invoke(new MethodInvoker(()=> {
                        RemoveTaskItem(taskItemData);
                    }));
                    break;
            }
        }


        /// <summary>
        /// 开始计算一条任务
        /// </summary>
        /// <param name="itemData"></param>
        private void AddTaskItem(Common.TaskItemData itemData)
        {
            string key = itemData.md5key;
            DS.Controls.DSFolderListItem item = new DS.Controls.DSFolderListItem(itemData);
            if (!taskItemDic.ContainsKey(key))
            {
                taskItemDic.Add(key, item);
                Common.ClientItemState itemState = taskItemDic.Count == 0 ? Common.ClientItemState.idle : Common.ClientItemState.busy;
                Common.ClientItemData clientItem = new Common.ClientItemData("", itemState, taskItemDic.Count);
                socketClient.Send(SC.MessageType.StateChange, clientItem);
                Common.Log.Info("向主机发送状态变更消息:" + clientItem.clientItemState);
            }
            Invoke(new MethodInvoker(() =>
            {
                    dSkinListBox1.Items.Add(item);
            }));

        }

        /// <summary>
        /// 一条任务结束
        /// </summary>
        /// <param name="itemData"></param>
        private void RemoveTaskItem(Common.TaskItemData itemData)
        {
            Invoke(new MethodInvoker(() =>
            {
                    string key = Common.MD5Hash.GetstrMD5(itemData.importpath);
                    if (taskItemDic.ContainsKey(key))
                    {
                        dSkinListBox1.Items.Remove(taskItemDic[key]);
                        taskItemDic.Remove(key);
                        Common.ClientItemState itemState = taskItemDic.Count == 0 ? Common.ClientItemState.idle : Common.ClientItemState.idle;
                        Common.ClientItemData clientItem = new Common.ClientItemData("", itemState, taskItemDic.Count);
                        socketClient.Send(SC.MessageType.StateChange, clientItem);
                    }
            }));

            Common.TaskItemData item = taskList2.FirstOrDefault(itemdata => itemdata.importpath == itemData.importpath);
            if (item != null)
            {
                taskList2.Remove(item);
            }
        }

        /// <summary>
        /// 常驻线程计算
        /// </summary>
        /// <param name="arguments"></param>
        public void Calculate(object obj)
        {
            while (true)
            {
                System.Threading.Thread.Sleep(100);
                if (taskList2 == null || taskList2.Count==0 || !bContinue)
                {
                    Thread.Sleep(100);
                }
                else if (taskList2.Count > 0)
                {

                    Common.TaskItemData itemData;
                    itemData = taskList2[0];
                    socketClient.Send(SC.MessageType.BeginTask, itemData.importpath);

                    Common.CMDCalc.ExeCalc(itemData,dSkinTextBox1.Text,dSkinTextBox2.Text);
                    //System.Threading.Thread.Sleep(100);

                    Console.WriteLine(itemData.importpath);
                    lock (taskList2)
                    {
                        RemoveTaskItem(itemData);
                        socketClient.Send(SC.MessageType.EndTask, itemData.importpath);
                    }
                }
            }
        }



        private void SetValue(string strValue)
        {
            this.txt_Log.AppendText(strValue + "\r \n");
        }



        /// <summary>
        /// 断开连接
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_CloseConnect_Click(object sender, EventArgs e)
        {
            socketClient.Close();
        }

        private void dSkinButton1_Click(object sender, EventArgs e)
        {
            //System.Diagnostics.Process.Start(@"C:\Users\win10\AppData\Local\Yandex\YandexBrowser\Application\browser.exe");  //直接调用打开文件

        }

        private void FrmClient_FormClosing(object sender, FormClosingEventArgs e)
        {
            if(!bExit)
            {
                e.Cancel = true;
            }
            this.Hide();
            //socketClient.SendCloseClient();
            bExit = false;
        }

        private void btClose_Click(object sender, EventArgs e)
        {
            //socketClient.SendCloseClient();


        }

        #region toolstripMenu 右键菜单栏
        bool bExit = false; //从toolstrip退出
        private void toolStripMenuExit_Click(object sender, EventArgs e)
        {
            socketClient.SendCloseClient();
            bExit = true;
            this.Close();
        }

        private void toolStripMenuShow_Click(object sender, EventArgs e)
        {
            RestoreWin();
        }

        private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            RestoreWin();
        }

        private void toolStripMenuStart_Click(object sender, EventArgs e)
        {
            bContinue = true;
        }

        private void toolStripMenuPause_Click(object sender, EventArgs e)
        {
            bContinue = false;
        }
        #endregion
    }
}